package com.yuntoyun.fwcore.plug.network.retrofit;
/*
 * +----------------------------------------------------------------------
 * | @Author: codeavatar   @Year：2021
 * +----------------------------------------------------------------------
 * | @Email: codeavatar@aliyun.com
 * +----------------------------------------------------------------------
 */
import android.content.Context;
import android.os.Message;

import com.yuntoyun.fwcore.config.FwAPIService;
import com.yuntoyun.fwcore.config.FwAppConfig;
import com.yuntoyun.fwcore.util.FwDialogUtil;
import com.yuntoyun.fwcore.util.FwLogUtil;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 网络工具类
 */
public class FwOkHttp<T> {

    private static FwOkHttp init = null;
    private static FwAPIService fwAPIService = null;
    private static Retrofit retrofit = null;
    private static OkHttpClient okHttpClient = null;

    public static FwOkHttp instance() {
        if (null == init) {
            init = new FwOkHttp();
        }
        return init;
    }

    private static void doInit() {
        //实例化OkHttpClient
        if (null == okHttpClient) {
            HttpLoggingInterceptor httpLoggingInterceptor =
                    new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {

                        @Override
                        public void log(String message) {
                            FwLogUtil.info("[FwOkHttp]", message);
                        }
                    }).setLevel(HttpLoggingInterceptor.Level.BODY);
            okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(httpLoggingInterceptor)
                    .retryOnConnectionFailure(true)
                    .connectTimeout(FwAppConfig.HTTP_TIMEOUT, TimeUnit.SECONDS)
                    .readTimeout(FwAppConfig.HTTP_TIMEOUT, TimeUnit.SECONDS)
                    .writeTimeout(FwAppConfig.HTTP_TIMEOUT, TimeUnit.SECONDS)
                    .build();
        }
        if (null == retrofit) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(FwAppConfig.ROOT_API)
                    .client(okHttpClient)
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        fwAPIService = retrofit.create(FwAPIService.class);
    }

    public static FwAPIService getFwAPIService() {
        if (null == fwAPIService) {
            doInit();
        }
        return fwAPIService;
    }

    public void doPost(Context context, final Message message,
                       Observable<T> observable, final
                       List<DisposableObserver>
                               subscriberList, boolean showloading) {
        if (showloading) {
            FwDialogUtil.showLoading(context, "", true);
        }

        DisposableObserver<T> disposableObserver = new
                DisposableObserver<T>() {

                    @Override
                    public void onNext(T model) {
                        message.obj = model;
                        message.sendToTarget();
                        subscriberList.clear();
                    }

                    @Override
                    public void onError(Throwable e) {
                        FwLogUtil.error("[Subscriber-onError]", e.getMessage());
                        subscriberList.clear();
                        FwDialogUtil.dismissLoading();
                    }

                    @Override
                    public void onComplete() {
                        subscriberList.clear();
                        FwDialogUtil.dismissLoading();
                    }
                };

        subscriberList.add(disposableObserver);
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(disposableObserver);
    }

    //=============================================================================================

    /**
     * 多个文件上传,Filelist
     *
     * @param maps      哈唏表型参
     * @param files     文件列表
     * @param imgKey    文件键名
     * @param isMore    true：多个文件，false：单个文件
     * @param isKeySort true：imgKey+[1-n]，false：imgKey[]
     * @return
     */
    public static List<MultipartBody.Part> getMultipartBody(HashMap<String,
            Object> maps, List<File> files, String imgKey, boolean isMore, boolean isKeySort) {
        MultipartBody.Builder mbBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (files != null && files.size() > 0) {
            for (int i = 0; i < files.size(); i++) {
                File file = files.get(i);
                RequestBody requestBody = RequestBody.create(MediaType.parse
                        ("multipart/form-data"), file);
                if (files.size() == 1 && !isMore) {
                    mbBuilder.addFormDataPart(imgKey, file.getName(), requestBody);
                } else {
                    mbBuilder.addFormDataPart(((isKeySort) ? imgKey + (i + 1) : imgKey + "[]"),
                            file.getName(), requestBody);
                }
            }
        }
        for (String key : maps.keySet()) {
//            mbBuilder.addFormDataPart(key, (String) maps.get(key));
            mbBuilder.addFormDataPart(key, String.valueOf(maps.get(key)));
        }

        return mbBuilder.build().parts();
    }

    /**
     * 多个文件上传,Filelist
     *
     * @param maps  哈唏表型参
     * @param files 文件列表
     * @param keys  指定文件键名列表
     * @return
     */
    public static List<MultipartBody.Part> getMultipartBody(HashMap<String, Object> maps,
                                                            List<File> files, List<String> keys) {
        MultipartBody.Builder mbBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if (files != null && files.size() > 0) {
            for (int i = 0; i < files.size(); i++) {
                File file = files.get(i);
                RequestBody requestBody = RequestBody.create(MediaType.parse
                        ("multipart/form-data"), file);
                mbBuilder.addFormDataPart(keys.get(i), file.getName(), requestBody);
            }
        }
        for (String key : maps.keySet()) {
//            mbBuilder.addFormDataPart(key, (String) maps.get(key));
            mbBuilder.addFormDataPart(key, String.valueOf(maps.get(key)));
        }
        String sdfdsf = mbBuilder.toString();
        return mbBuilder.build().parts();
    }

}
